home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Die Speccy' 97
/
Die Speccy' 97.iso
/
amiga_system
/
the_aminet
/
util
/
boot
/
avwm.lzh
/
avwm-0.4
/
jumptable.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-08
|
5KB
|
165 lines
/*
InstallWedge, RemoveWedge and GetJumpTable were taken from
UnixDirsII (by Martin W. Scott, mws@castle.ed.ac.uk)
They are based on a method used in ISpy, a CBM-provided AmigaMail example.
*/
#include <dos.h>
#include <signal.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/semaphores.h>
#include <string.h>
#include <proto/exec.h>
/* The name this JumpTable/Semaphore will get. */
UBYTE *JTName = "AVWM-WindowMonitor-JT";
#include "wbwm.h"
#include "jumptable.h"
extern struct LVOTable LVOArray[NUMBEROFFUNCTIONS];
BOOL
InstallWedge (VOID)
{
struct JumpTable *jumptable;
ULONG *addressptr;
UCOUNT i, j;
Forbid ();
/* Get pointer to JumpTable. Create it if necessary */
if (jumptable = GetJumpTable (JTName))
{
/* Try to get exclusive lock on semaphore, in case it already existed. */
if (AttemptSemaphore ((struct SignalSemaphore *) jumptable))
{
/* Make sure nobody else has function addresses in the jumptable */
if (jumptable->jt_Owner == NULL)
{
jumptable->jt_Owner = FindTask (0);
/* Don't want to disable any longer than necessary */
Disable ();
for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
{
/* Replace addresses in the jumptable with my own. */
addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
(*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
*addressptr = (ULONG) LVOArray[j].lt_newFunction;
}
Enable ();
}
else
printf ("Already running.\n");
ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
}
else
printf ("Can't lock table.\n");
}
else
printf ("Can't create jumptable\n");
Permit ();
return ((BOOL) jumptable);
}
BOOL
RemoveWedge (VOID)
{
struct JumpTable *jumptable;
ULONG *addressptr;
UCOUNT i, j;
Forbid ();
if (jumptable = GetJumpTable (JTName))
{
/* Check if this task owns this jumptable */
if (jumptable->jt_Owner == FindTask (0))
{
/* Get the semaphore exclusively.
* Depending on what got SetFunction ()'ed this could take some time.
* Also note that shared locks are used to indicate the code is
* being executed and that shared locks can jump ahead of queue'ed
* exclusive locks, adding to the waittime.
*/
ObtainSemaphore ((struct SignalSemaphore *) jumptable);
Disable ();
/* Restore old pointers in jumptable */
for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
{
addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
*addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
}
Enable ();
jumptable->jt_Owner = NULL;
ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
}
}
Permit ();
return (TRUE);
}
struct JumpTable *
GetJumpTable (UBYTE * name)
{
struct JumpTable *jumptable;
ULONG *addressptr;
UWORD *jmpinstr;
UBYTE *jtname;
UCOUNT i, j;
/* Not really necessary to forbid again, just to indicate that I don't
* want another task to create the semaphore while I'm trying to do the
* same. Here GetJumpTable () is only called from InstallWedge (), so it
* will just bump the forbid count.
*/
Forbid ();
if (!(jumptable = (struct JumpTable *) FindSemaphore (name)))
{
if (jumptable = AllocMem (sizeof (struct JumpTable), MEMF_PUBLIC | MEMF_CLEAR))
{
if (jtname = AllocMem (strlen (name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
{
for (i = 0, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
{
jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
*jmpinstr = 0x4EF9;
addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
*addressptr = (ULONG) SetFunction (
(struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
LVOArray[j].lt_LVO,
(VOID *) ((UBYTE *) jumptable->jt_Function + i)
);
}
jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
strcpy (jtname, name);
jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
AddSemaphore ((struct SignalSemaphore *) jumptable);
}
else {
FreeMem (jumptable, sizeof (struct JumpTable));
jumptable = NULL;
}
}
}
Permit ();
/* If succeeded, you now have a jumptable which entries point to the original
* library functions. If another task SetFunction ()'ed one or more of those
* already, that task can never go away anymore.
*/
return (jumptable);
}